import javax.swing.*;
import java.lang.reflect.Array;
import java.util.Random;
import java.util.*;

/*******************************************************
 *
 *  Name    :  Levi Kushlan
 *  Team Name: Unonymous
 *  Project :  UNO Game
 *  Main    :  Game.java
 *  Date    :  9/27/2012
 *
 ********************************************************/
public class Game {

    public static void main(String args []){
        Card [] card = new Card[108];
        Deck deck = new Deck(card);
        Card [] hand1 = new Card[50];
        Card [] hand2 = new Card[50];
        Card [] hand3 = new Card[50];
        Card [] hand4 = new Card[50];
        Card [] hand5 = new Card[50];
        int index = 0,numberOfPlayers=3; int hand1Index =0,hand2Index =0,hand3Index=0,hand4Index=0,hand5Index=0,card3Left=7,card4Left=7,cardLeft = 7,card1Left=7,card2Left=7;
        String info = "";
        String input=""; int put =0 ; boolean skip = false; boolean continuePlay = true;
        List <Card> cards = Arrays.asList(card);
        card = deck.Fill(card); //Fill with cards
        Collections.shuffle(cards); //shuffle cards list

        Card topCard = card [index]; index++; //Create first flipped card

        while(continuePlay)
        switch(MainMenu("What would you like to do?")){
            case 0:    continuePlay = false;
                break;
            case 1: try{numberOfPlayers = Integer.parseInt(JOptionPane.showInputDialog("How many players are you playing with?  \nLimit(2-5) Current number: "+numberOfPlayers));
                if(numberOfPlayers <2||numberOfPlayers>5)
                numberOfPlayers = 3;
                    }catch(Exception ex){}
                break;                           
            default:   if(Exit() == 0)
                        System.exit(0);
                break;
        }
        continuePlay = true;
        for(int i = 0; i < 7; i++){             //Create hands
            hand1[i] = card[index];
            card[index] = null;
            index++; hand1Index++;
        }
        for(int i = 0; i < 7; i++){
            hand2[i] = card[index];
            card [index] = null;
            index++; hand2Index++;
        }
        if(numberOfPlayers >2)
        for(int i = 0; i < 7; i++){
            hand3[i] = card[index];
            card [index] = null;
            index++; hand3Index++;
        }
        if(numberOfPlayers >3)
        for(int i = 0; i < 7; i++){
            hand4[i] = card[index];
            card [index] = null;
            index++; hand4Index++;
        }
        if(numberOfPlayers >4)
        for(int i = 0; i < 7; i++){
            hand5[i] = card[index];
            card [index] = null;
            index++; hand5Index++;
        }

        while(true){
            if(topCard.getFace()==14&&topCard.getValue()==50){
                hand1[hand1Index] = card[index]; index++; hand1Index++; cardLeft++;
                hand1[hand1Index] = card[index]; index++; hand1Index++; cardLeft++;
                hand1[hand1Index] = card[index]; index++; hand1Index++; cardLeft++;
                hand1[hand1Index] = card[index]; index++; hand1Index++; cardLeft++;
                JOptionPane.showMessageDialog(null,"Player 1 drew four cards and was skipped.");
                skip =true;
            }
            if(topCard.getFace()==12&&topCard.getValue()==20 ){
                hand1[hand1Index] = card[index]; index++; hand1Index++; cardLeft++;
                hand1[hand1Index] = card[index]; index++; hand1Index++; cardLeft++;
                topCard = new Card(12,0,topCard.getColor());
                JOptionPane.showMessageDialog(null,"Player 1 drew two cards and was skipped.");
                skip =true;
            }
            if(topCard.getFace() > 12)                 //Deal with wild cards
                topCard = TakeAction(topCard);
            if(topCard.getFace() == 11&&topCard.getValue()==20){
                skip = true;
                JOptionPane.showMessageDialog(null,"Player 1 was skipped.");
                topCard = new Card(11,0,topCard.getColor());
            }

           if(!skip){
           while(continuePlay)
                switch(Menu(topCard.toString(),"Player 1")){                            //Player 1
                    case 0:     JOptionPane.showMessageDialog(null,hand1);
                        break;
                    case 1:     for (int i=0; i < hand1Index; i++) {
                                    info += String.valueOf(i)+". "+hand1[i];
                                }
                            try{
                                input = JOptionPane.showInputDialog("What card do you want to play?(Type number by card.)\nTop Card: "+topCard.toString()+"\n"+info);
                                info = "";
                                put = Integer.parseInt(input);                    //play card
                            if(Playable(hand1[put],topCard))
                            {
                                topCard = hand1[put];
                                cardLeft--;
                                hand1[put] = new Card (111,0,"USED");
                                continuePlay = false;
                            }
                            else
                                JOptionPane.showMessageDialog(null,hand1[put].toString()+" Is not a legal play.");
                        } catch(Exception ex){}
                        break;
                    case 2:  hand1[hand1Index] = card[index]; index++; hand1Index++; continuePlay = false;   //draw card
                        cardLeft++;
                        break;
                    default: if(Exit() == 0)
                        System.exit(0);
                        break;
                }
           }
            continuePlay = true;
            skip = false;

            if(topCard.getFace()==14&&topCard.getValue()==50){                             //Deal with Draw fours
                hand2[hand2Index] = card[index]; index++; hand2Index++; card1Left++;
                hand2[hand2Index] = card[index]; index++; hand2Index++; card1Left++;
                hand2[hand2Index] = card[index]; index++; hand2Index++; card1Left++;
                hand2[hand2Index] = card[index]; index++; hand2Index++; card1Left++;
                JOptionPane.showMessageDialog(null,"Player 2 drew four cards and was skipped.");
                skip =true;
            }
            if(topCard.getFace() > 12)
                topCard = TakeAction(topCard);
            if(topCard.getFace() == 11&&topCard.getValue()==20){
                skip = true;
                topCard = new Card(11,0,topCard.getColor());
                JOptionPane.showMessageDialog(null,"Player 2 was skipped.");
            }
            if(topCard.getFace()==12&&topCard.getValue()==20 ){
                hand2[hand2Index] = card[index]; index++; hand2Index++;  card1Left++;
                hand2[hand2Index] = card[index]; index++; hand2Index++;  card1Left++;
                topCard = new Card(12,0,topCard.getColor());
                JOptionPane.showMessageDialog(null,"Player 2 drew two cards and was skipped.");
                skip =true;
            }

            if(!skip){
                while(continuePlay){
                    switch(Menu(topCard.toString(),"Player 2")){             //Player 2
                        case 0:  JOptionPane.showMessageDialog(null,hand2);
                            break;
                        case 1: for (int i=0; i < hand2Index; i++) {
                                    info += String.valueOf(i)+". "+hand2[i];
                                }
                            try{
                            input = JOptionPane.showInputDialog("What card do you want to play?(Type number by card.)\nTop Card: "+topCard.toString()+"\n"+info);
                            info = "";
                            put = Integer.parseInt(input);

                                if(Playable(hand2[put],topCard))
                                {
                                    topCard = hand2[put];
                                    card1Left = card1Left -1;
                                    hand2[put] = new Card (111,0,"USED");
                                    continuePlay = false;
                                }
                                else
                                    JOptionPane.showMessageDialog(null,hand2[put].toString()+" Is not a legal play.");
                               } catch(Exception ex){}
                             break;
                        case 2:  hand2[hand2Index] = card[index]; index++; hand2Index++; continuePlay = false;
                                card1Left++;
                            break;
                        default: if(Exit() == 0)
                                System.exit(0);
                       }
                }
                }
                continuePlay = true;
                skip = false;

                if(topCard.getFace()==14&&topCard.getValue()==50){
                    hand3[hand3Index] = card[index]; index++; hand3Index++; card2Left++;
                    hand3[hand3Index] = card[index]; index++; hand3Index++; card2Left++;
                    hand3[hand3Index] = card[index]; index++; hand3Index++; card2Left++;
                    hand3[hand3Index] = card[index]; index++; hand3Index++; card2Left++;
                JOptionPane.showMessageDialog(null,"Player 3 drew four cards and was skipped.");
                    skip =true;
                }
            if(topCard.getFace()==12&&topCard.getValue()==20 ){
                hand3[hand3Index] = card[index]; index++; hand3Index++; card2Left++;
                hand3[hand3Index] = card[index]; index++; hand3Index++; card2Left++;
                topCard = new Card(12,0,topCard.getColor());
                JOptionPane.showMessageDialog(null,"Player 3 drew two cards and was skipped.");
                skip =true;
            }
            if(topCard.getFace() > 12)                 //Deal with wild cards
                topCard = TakeAction(topCard);
            if(topCard.getFace() == 11&&topCard.getValue()==20){
                skip = true;
                topCard = new Card(11,0,topCard.getColor());
                JOptionPane.showMessageDialog(null,"Player 3 was skipped.");
            }
           if(!skip){
                while(continuePlay)
                switch(Menu(topCard.toString(),"Player 3")){                            //player 3
                    case 0:  JOptionPane.showMessageDialog(null,hand3);
                        break;
                    case 1: for (int i=0; i < hand3Index; i++) {
                                info += String.valueOf(i)+". "+hand3[i];
                            }
                        try{
                            input = JOptionPane.showInputDialog("What card do you want to play?(Type number by card.)\nTop Card: "+topCard.toString()+"\n"+info);
                            info = "";
                            put = Integer.parseInt(input);

                                                                               //play card
                            if(Playable(hand3[put],topCard))
                            {
                                topCard = hand3[put];
                                card2Left--;
                                hand3[put] = new Card (111,0,"USED");
                                continuePlay = false;
                            }
                            else
                                JOptionPane.showMessageDialog(null,hand3[put].toString()+" Is not a legal play.");
                        } catch(Exception ex){}
                        break;
                    case 2:  hand3[hand3Index] = card[index]; index++; hand3Index++; continuePlay = false;   //draw card
                        card2Left++;
                        break;
                    default: if(Exit() == 0)
                        System.exit(0);
                }
           }
                continuePlay = true;
                skip = false;
           if(numberOfPlayers ==4||numberOfPlayers==5){
                if(topCard.getFace()==14&&topCard.getValue()==50){              //Player 4
                hand4[hand4Index] = card[index]; index++; hand4Index++; card3Left++;
                hand4[hand4Index] = card[index]; index++; hand4Index++; card3Left++;
                hand4[hand4Index] = card[index]; index++; hand4Index++; card3Left++;
                hand4[hand4Index] = card[index]; index++; hand4Index++; card3Left++;
                JOptionPane.showMessageDialog(null,"Player 4 drew four cards and was skipped.");
                skip =true;
            }
            if(topCard.getFace()==12&&topCard.getValue()==20 ){
                hand4[hand4Index] = card[index]; index++; hand4Index++; card3Left++;
                hand4[hand4Index] = card[index]; index++; hand4Index++; card3Left++;
                topCard = new Card(12,0,topCard.getColor());
                JOptionPane.showMessageDialog(null,"Player 4 drew two cards and was skipped.");
                skip =true;
            }
            if(topCard.getFace() > 12)                 //Deal with wild cards
                topCard = TakeAction(topCard);
            if(topCard.getFace() == 11&&topCard.getValue()==20){
                skip = true;
                topCard = new Card(11,0,topCard.getColor());
                JOptionPane.showMessageDialog(null,"Player 4 was skipped.");
            }

           if(!skip){
           while(continuePlay)
                switch(Menu(topCard.toString(),"Player 4")){                            //Player 4
                    case 0:     JOptionPane.showMessageDialog(null,hand4);
                        break;
                    case 1:     for (int i=0; i < hand4Index; i++) {
                                    info += String.valueOf(i)+". "+hand4[i];
                                }
                            try{
                                input = JOptionPane.showInputDialog("What card do you want to play?(Type number by card.)\nTop Card: "+topCard.toString()+"\n"+info);
                                info = "";
                                put = Integer.parseInt(input);                    //play card
                            if(Playable(hand4[put],topCard))
                            {
                                topCard = hand4[put];
                                card3Left--;
                                hand4[put] = new Card (111,0,"USED");
                                continuePlay = false;
                            }
                            else
                                JOptionPane.showMessageDialog(null,hand4[put].toString()+" Is not a legal play.");
                        } catch(Exception ex){}
                        break;
                    case 2:  hand4[hand4Index] = card[index]; index++; hand4Index++; continuePlay = false;   //draw card
                        card3Left++;
                        break;
                    default: if(Exit() == 0)
                        System.exit(0);
                        break;
                }
           }
            continuePlay = true;
            skip = false;
           }//end if(numPlayers)
           if(numberOfPlayers==5){
                if(topCard.getFace()==14&&topCard.getValue()==50){
                hand5[hand5Index] = card[index]; index++; hand5Index++; card4Left++;
                hand5[hand5Index] = card[index]; index++; hand5Index++; card4Left++;
                hand5[hand5Index] = card[index]; index++; hand5Index++; card4Left++;
                hand5[hand5Index] = card[index]; index++; hand5Index++; card4Left++;
                JOptionPane.showMessageDialog(null,"Player 5 drew four cards and was skipped.");
                skip =true;
            }
            if(topCard.getFace()==12&&topCard.getValue()==20 ){
                hand5[hand5Index] = card[index]; index++; hand5Index++; card4Left++;
                hand5[hand5Index] = card[index]; index++; hand5Index++; card4Left++;
                topCard = new Card(12,0,topCard.getColor());
                JOptionPane.showMessageDialog(null,"Player 5 drew two cards and was skipped.");
                skip =true;
            }
            if(topCard.getFace() > 12)                 //Deal with wild cards
                topCard = TakeAction(topCard);
            if(topCard.getFace() == 11&&topCard.getValue()==20){
                skip = true;
                topCard = new Card(11,0,topCard.getColor());
                JOptionPane.showMessageDialog(null,"Player 5 was skipped.");
            }

           if(!skip){
           while(continuePlay)
                switch(Menu(topCard.toString(),"Player 5")){                            //Player 5
                    case 0:     JOptionPane.showMessageDialog(null,hand5);
                        break;
                    case 1:     for (int i=0; i < hand5Index; i++) {
                                    info += String.valueOf(i)+". "+hand5[i];
                                }
                            try{
                                input = JOptionPane.showInputDialog("What card do you want to play?(Type number by card.)\nTop Card: "+topCard.toString()+"\n"+info);
                                info = "";
                                put = Integer.parseInt(input);                    //play card
                            if(Playable(hand5[put],topCard))
                            {
                                topCard = hand5[put];
                                card4Left--;
                                hand5[put] = new Card (111,0,"USED");
                                continuePlay = false;
                            }
                            else
                                JOptionPane.showMessageDialog(null,hand5[put].toString()+" Is not a legal play.");
                        } catch(Exception ex){}
                        break;
                    case 2:  hand5[hand5Index] = card[index]; index++; hand5Index++; continuePlay = false;   //draw card
                        card4Left++;
                        break;
                    default: if(Exit() == 0)
                        System.exit(0);
                        break;
                }
           }
            continuePlay = true;
            skip = false;
           }//end if(numPlayers)
                if(cardLeft ==0||card1Left==0||card2Left==0||card3Left==0||card4Left==0)
                    break;
                }//end while
                if(cardLeft ==0)
                    JOptionPane.showMessageDialog(null,"Player 1 has won!");
                if(card3Left ==0)
                    JOptionPane.showMessageDialog(null,"Player 4 has won!");
                if(card1Left ==0)
                    JOptionPane.showMessageDialog(null,"Player 2 has won!");
                if(card2Left ==0)
                    JOptionPane.showMessageDialog(null,"Player 3 has won!");
                if(card4Left ==0)
                    JOptionPane.showMessageDialog(null,"Player 5 has won!");

                JOptionPane.showMessageDialog(null,"Player 1 points: "+CalculatePoints(hand1,hand1Index)+"\nPlayer 2 points: "+
                        CalculatePoints(hand2,hand2Index)+"\nPlayer 3 points: "+CalculatePoints(hand3,hand3Index)+"\nPlayer 4 points: "+
                        CalculatePoints(hand4,hand4Index)+"\nPlayer 5 points: "+CalculatePoints(hand5,hand5Index));
    }//end main
    public static int Player(){


        return 0;
    }

    public static int Menu(String data,String player)
	{
		String[] choices = {"View hand", "Play card","Draw card"};

		int response = JOptionPane.showOptionDialog(
		null
		,"Top Card: " + data
		,player
		,JOptionPane.YES_NO_OPTION,JOptionPane.PLAIN_MESSAGE,null,choices,"");
		return response;
	}
    public static int MainMenu(String data)
	{
		String[] choices = {"Play UNO Game","Edit Number of players","Close Program"};

		int response = JOptionPane.showOptionDialog(null
		,data
		,"Main Menu"
		,JOptionPane.YES_NO_OPTION,JOptionPane.PLAIN_MESSAGE,null,choices,"");
		return response;
	}
    public static int Exit()
	{
        String [] choices = new String [2];
        choices[0] = "Yes";
        choices[1] = "No";

		int response = JOptionPane.showOptionDialog(
		null
		,"Are you sure you want to quit?"
		,"Question"
		,JOptionPane.YES_NO_OPTION
		,JOptionPane.PLAIN_MESSAGE
		,null
		,choices
		,"");
		return response;
	}

    public static Card TakeAction(Card top){

        if(top.getFace() ==14&&top.getValue()!=0){

        int number = Integer.parseInt(JOptionPane.showInputDialog("What Color 1-4 1.Yellow 2.Red 3.Blue 4. Green"));
        switch(number){
            case 1:    top = new Card(14,0,"Yellow");
                break;
            case 2:    top = new Card(14,0,"Red");
                break;
            case 3:    top = new Card(14,0,"Blue");
                break;
            case 4:    top = new Card(14,0,"Green");
                break;
        }
        }
        if(top.getFace() ==13&&top.getValue()!=0){
        int number = Integer.parseInt(JOptionPane.showInputDialog("What Color 1-4 1.Yellow 2.Red 3.Blue 4. Green"));
        switch(number){
            case 1:    top = new Card(13,0,"Yellow");
                break;
            case 2:    top = new Card(13,0,"Red");
                break;
            case 3:    top = new Card(13,0,"Blue");
                break;
            case 4:    top = new Card(13,0,"Green");
                break;
        }
        }
        return top;
    }

    public static int CalculatePoints(Card [] card,int index){
        int points=0;
        for (int i=0; i < index; i++) {
            points += card[i].getValue();
        }
        return points;
    }

    public static boolean Playable(Card card1,Card card2){


        if(card1.getFace()==13)
            return true;
        if(card1.getFace()==14)
            return true;
        if(card1.compareTo(card2)==0)
            return true;
        if(card1.getFace() == card2.getFace())
            return true;
        if(card1.getColor().equalsIgnoreCase(card2.getColor()))
            return true;

        return false;
    }
}
